////implementation of Groovey

#include "groovey.hpp"
#include <GL/glut.h>

Groovey::Groovey(void (*Render_Driver)(),void (*Transform_Driver)()): renderActive(false)
{
    p_list = new GParticle_List;
    t_list = new GTransformer_List;
    r_list = new GRenderer_List;
    rdrvr = Render_Driver;
    tdrvr = Transform_Driver;
    
    GRenderer gr;
    r_list->addRenderer(gr);
    
    boost::numeric::ublas::vector<float> zero (2);
    zero[0] = 0;
    zero[1] = 0;
    
    ////first, define a particle and send it off to the factory
    GParticle gp(6,1,zero,zero,zero);
    p_list->Create(gp,15);
    ///hooray! We should now have lots of little particles in our particle list
    
    ///now lets make a transformer that does gravity, oy?
    boost::numeric::ublas::vector<float> fg (2);// force of gravity
    fg[0] = 0;
    fg[1] = -0.06;
    
    GTransformer grav(fg);							//gravity transform
    t_list->addTransform(grav);
    
    ///we have initialized a Particle, Transform, and Renderer List. Cool beans, dude.
    ////let us continue gracefully.... *crashes into dunkin' donuts with a krispy kreme truck*
    
}/////////////////Groovey System Constructor

void Groovey::Feed(GParticle_List& GPlist)
{
    delete p_list;
    p_list = &GPlist;
}/////////////////Feed (Particle List)

void Groovey::Feed(GTransformer_List& GTlist)
{
    delete t_list;
    t_list = &GTlist;
}/////////////////Feed (Transformer List)

void Groovey::Feed(GRenderer_List& GRlist)
{
    delete r_list;
    r_list = &GRlist;
}/////////////////Feed (Renderer List)
void Groovey::letsRoll(int argc, char **argv)
{
    renderActive = true;
    
    boost::thread tTrans(tdrvr);
    
    glutInit(&argc, argv);
    
    glutInitWindowPosition(300 , 200);
    
    glutInitWindowSize(500,500);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );//| GLUT_DEPTH);
    
    glutCreateWindow("Hoody hoo!");
    
    glutDisplayFunc(rdrvr);
    
    glutIdleFunc(rdrvr);
    
    glutMainLoop();
    
    renderActive = false;
    
    tTrans.join();
    ///we are done... exit gracefully
    
    ///woo!
}/////////////////let's roll, sistah! creation thread

void Groovey::renderParticles()
{
    r_list->render(*p_list);
}/////////////////Rendering function

void Groovey::transformLoop()
{
    int i;
    while (renderActive){
        
        ///Autobots: transform and roll out!!!
        for (i = p_list->getSize() - 1; i >= 0 ; --i){
        	t_list->Feed_once((*p_list)[i]);
        }
	    boost::mutex::scoped_lock lk(p_list->updateLock());
	    
	    if (p_list->Updated()){///if the list is already updated
	       (p_list->getRdyToUpdate()).wait(lk);///wait until it needs another update
        }
        
        for (i = p_list->getSize() - 1; i >= 0 ; --i){
        	(*p_list)[i].UpdateSet(1000,1000);
        }
        
        p_list->updateOpen();
    }
}/////////////////Transformer Loop

Groovey::~Groovey()
{
    delete r_list;
    delete t_list;
    delete p_list;
}/////////////////OBLITERATE!!!! *KABLAM! Suckahz*
